package stone926.mods.more_enchantments.enchantments;

import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.EnchantmentTarget;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityGroup;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.server.world.ServerWorld;
import stone926.mods.more_enchantments.MoreEnchantmentsMod;
import stone926.mods.more_enchantments.damage.StoneEntityDamageSource;
import stone926.mods.more_enchantments.interfaces.ILivingEntity;
import stone926.mods.more_enchantments.util.RandomUtil;

import java.util.Random;

import static stone926.mods.more_enchantments.enchantments.CooldownShorterEnchantment.getShorterCooldown;

public class WinPeopleByVirtueEnchantment extends Enchantment {

  public WinPeopleByVirtueEnchantment() {
    super(Rarity.RARE, EnchantmentTarget.WEAPON, new EquipmentSlot[]{EquipmentSlot.MAINHAND});
  }

  public static float getAttackDamage(int level) {
    return level + new Random().nextInt(level * 3 + 1);
  }

  public static int getEffectDuration(int lvl) {
    return 3 * lvl * 20;
  }

  public static double getPoisoningProbability(int lvl) {
    return 0.15 * lvl;
  }

  public static int getAmplifier(int lvl) {
    return lvl;
  }

  public static int getFireDuration(int lvl) {
    return lvl * 4; // second
  }

  public static int getCoolDown(int lvl) {
    return 95 * lvl + new Random().nextInt(10) * lvl;
  }

  public static int getParticleCount(int lvl) {
    return 10 * lvl;
  }

  @Override
  public int getMinPower(int level) {
    return 5 + 10 * (level - 1);
  }

  @Override
  public int getMaxLevel() {
    return 5;
  }

  @Override
  public boolean isTreasure() {
    return true;
  }

  @Override
  public boolean isAcceptableItem(ItemStack stack) {
    return stack.getItem() == Items.BRICK || stack.getItem() == Items.NETHER_BRICK;
  }

  @Override
  public void onTargetDamaged(LivingEntity user, Entity target, int level) {
    super.onTargetDamaged(user, target, level);
    if (user instanceof PlayerEntity player
      && player.getItemCooldownManager().isCoolingDown(user.getMainHandStack().getItem())) {return;}

    boolean isCritical = user.fallDistance > 0.0F
      && !user.isOnGround()
      && !user.isClimbing()
      && !user.isTouchingWater()
      && !user.hasStatusEffect(StatusEffects.BLINDNESS)
      && !user.hasVehicle()
      && !user.isSprinting()
      && target instanceof LivingEntity;

    if (isCritical) {
      LivingEntity l = (LivingEntity) target;
      int duration = getEffectDuration(level);
      int amplifier = getAmplifier(level);

      l.addStatusEffect(new StatusEffectInstance(StatusEffects.BLINDNESS, duration), user);
      l.addStatusEffect(new StatusEffectInstance(StatusEffects.WEAKNESS, duration, amplifier), user);
      l.addStatusEffect(new StatusEffectInstance(StatusEffects.SLOWNESS, duration, amplifier), user);
      l.addStatusEffect(new StatusEffectInstance(StatusEffects.NAUSEA, duration), user);
      l.addStatusEffect(new StatusEffectInstance(StatusEffects.HUNGER, duration, amplifier), user);

      RandomUtil.runIfPossible(getPoisoningProbability(level), user.getRandom(), () -> l.addStatusEffect(new StatusEffectInstance(StatusEffects.POISON, duration, amplifier), user));

      ((ILivingEntity) l).forceDamage(StoneEntityDamageSource.virtue(user), getAttackDamage(level));

      if (Items.NETHER_BRICK.equals(user.getMainHandStack().getItem())) {
        target.setOnFireFor(getFireDuration(level));
      }

      int shorterLvl = EnchantmentHelper.getEquipmentLevel(MoreEnchantmentsMod.COOLDOWN_SHORTER, user);
      if (user instanceof PlayerEntity player) {
        player.getItemCooldownManager().set(
          Items.BRICK, (int) Math.round(getCoolDown(level) * getShorterCooldown(shorterLvl))
        );
        player.getItemCooldownManager().set(
          Items.NETHER_BRICK, (int) Math.round(getCoolDown(level) * getShorterCooldown(shorterLvl))
        );
      }

      String name = user.getMainHandStack().getName().getString();
      if ("Virtue".equals(name) || "德".equals(name)) {
        if (target.getEntityWorld() instanceof ServerWorld server) {
          server.spawnParticles(
            ParticleTypes.EXPLOSION,
            target.getX(), target.getY() + target.getEyeHeight(target.getPose()), target.getZ(),
            getParticleCount(level),
            0.1, 0.1, 0.1,
            0
          );
        }
      }
    }
  }

  @Override
  public float getAttackDamage(int level, EntityGroup group) {
    return level / 2F;
  }

}
